package org.go;

import java.util.Calendar;
import java.util.Date;

import org.go.scheduler.Scheduler;
import org.go.trigger.Trigger;
import org.go.work.WorkDataMap;

/**
 * 
 * @author hejie
 *
 */
public interface GoContext<T> {
	/**
	 * Get the value with the given key from the context's data map.
	 * 
	 * @param key
	 */
	Object get(Object key);

	/**
	 * <p>
	 * Get a handle to the <code>Calendar</code> referenced by the <code>Trigger</code>
	 * instance that fired the <code>Job</code>.
	 * </p>
	 */
	Calendar getCalendar();

	/**
	 * The actual time the trigger fired. For instance the scheduled time may
	 * have been 10:00:00 but the actual fire time may have been 10:00:03 if
	 * the scheduler was too busy.
	 * 
	 * @return Returns the fireTime.
	 * @see #getScheduledFireTime()
	 */
	Date getFireTime();

	/**
	 * <p>
	 * Get the <code>JobDetail</code> associated with the <code>Job</code>.
	 * </p>
	 */
	// public JobDetail getJobDetail();

	/**
	 * <p>
	 * Get the instance of the <code>Job</code> that was created for this
	 * execution.
	 * </p>
	 * 
	 * <p>
	 * Note: The Job instance is not available through remote scheduler
	 * interfaces.
	 * </p>
	 */
	//public Job getJobInstance();

	/**
	 * The amount of time the job ran for (in milliseconds).  The returned 
	 * value will be -1 until the job has actually completed (or thrown an 
	 * exception), and is therefore generally only useful to 
	 * <code>JobListener</code>s and <code>TriggerListener</code>s.
	 * 
	 * @return Returns the jobRunTime.
	 */
	long getJobRunTime();

	WorkDataMap getMergedJobDataMap();

	/**
	 * <p>
	 * Get the convenience <code>JobDataMap</code> of this execution context.
	 * </p>
	 * 
	 * <p>
	 * The <code>JobDataMap</code> found on this object serves as a convenience -
	 * it is a merge of the <code>JobDataMap</code> found on the 
	 * <code>JobDetail</code> and the one found on the <code>Trigger</code>, with 
	 * the value in the latter overriding any same-named values in the former.
	 * <i>It is thus considered a 'best practice' that the execute code of a Job
	 * retrieve data from the JobDataMap found on this object.</i>
	 * </p>
	 * 
	 * <p>NOTE: Do not
	 * expect value 'set' into this JobDataMap to somehow be set back onto a
	 * <code>StatefulJob</code>'s own JobDataMap.
	 * </p>
	 * 
	 * <p>
	 * Attempts to change the contents of this map typically result in an 
	 * <code>IllegalStateException</code>.
	 * </p>
	 * 
	 */
	//public JobDataMap getMergedJobDataMap();

	Date getNextFireTime();

	Date getPreviousFireTime();

	int getRefireCount();

	/**
	 * Returns the result (if any) that the <code>Job</code> set before its 
	 * execution completed (the type of object set as the result is entirely up 
	 * to the particular job).
	 * 
	 * <p>
	 * The result itself is meaningless to Quartz, but may be informative
	 * to <code>{@link GoListener}s</code> or 
	 * <code>{@link TriggerListener}s</code> that are watching the job's 
	 * execution.
	 * </p> 
	 * 
	 * @return Returns the result.
	 */
	Object getResult();

	/**
	 * The scheduled time the trigger fired for. For instance the scheduled
	 * time may have been 10:00:00 but the actual fire time may have been
	 * 10:00:03 if the scheduler was too busy.
	 * 
	 * @return Returns the scheduledFireTime.
	 * @see #getFireTime()
	 */
	Date getScheduledFireTime();

	/**
	 * <p>
	 * Get a handle to the <code>Scheduler</code> instance that fired the
	 * <code>Job</code>.
	 * </p>
	 */
	Scheduler getScheduler();

	/**
	 * <p>
	 * Get a handle to the <code>Trigger</code> instance that fired the
	 * <code>Job</code>.
	 * </p>
	 */
	Trigger getTrigger();

	/**
	 * <p>
	 * If the <code>Job</code> is being re-executed because of a 'recovery'
	 * situation, this method will return <code>true</code>.
	 * </p>
	 */
	boolean isRecovering();

	/**
	 * Put the specified value into the context's data map with the given key.
	 * Possibly useful for sharing data between listeners and jobs.
	 *
	 * <p>NOTE: this data is volatile - it is lost after the job execution
	 * completes, and all TriggerListeners and JobListeners have been 
	 * notified.</p> 
	 *  
	 * @param key
	 * @param value
	 */
	void put(Object key, Object value);

	/**
	 * Set the result (if any) of the <code>Job</code>'s execution (the type of 
	 * object set as the result is entirely up to the particular job).
	 * 
	 * <p>
	 * The result itself is meaningless to Quartz, but may be informative
	 * to <code>{@link GoListener}s</code> or 
	 * <code>{@link TriggerListener}s</code> that are watching the job's 
	 * execution.
	 * </p> 
	 */
	void setResult(Object result);
}
